package com.itbaizhan.test.innerClass;

/**
 * 测试内部类的用法
 * 把一个类放在另一个类的内部定义，称为内部类（ inner class）
 * 内部类提供了更好的封装，只好让外部类直接访问，不允许同一个包中的其他类直接访问
 * 内部类可以直接访问外部类的私有属性，内部类被当成其外部类的成员。但外部类
   不能访问内部类属性
 */
/*注意：
* 内部类只是一个编译时概念，一旦我们编译成功，就会成为完全不同的两个类，对于一
* 个名为Outer的外部类和其内部定义的名为Inner的内部类。编译完成后会出现Outer.class
* 和Outer$Inner.class两个类的字节码文件。所以内部类是相对独立的一种存在，
* 其成员变量/方法名可以和外部类相同*/
/*
* 内部类的访问
* 外部类中定义内部类：new Inner()
* 外部类以外的地方使用非静态内部类：Outer.Inner varname = new Outer().new Inner()*/

public class Outer {
    private int age=10;
    public void show(){
        System.out.println("Outer.show");
        System.out.println(age);

    }
    //内部类
    /*非静态内部类（外部类里使用非静态内部类和平时使用其他类没什么不同）
    1， 非静态内部类对象 必须存在一个 外部类对象里。因此，如果有一个非静态内部类
      对象那么一定存在对应的外部类对象。非静态内部类对象单独属于外部类的某个对象
    2， 非静态内部类可以 直接访问 外部为的成员，但是外部类不能直接访问非静态内部类成员
    3，非静态内部类不能有静态方法、静态属性和静态初始化块
    4，成员变量访问要点：
                     1.内部类属性：this.变量名
                      2.外部类属属性：外部类名.this.变量名*/
    public class Inner {  //如果写private修饰，只可以在这里被访问，外面的不能该买问
        int age = 20;
        public void show (){
            System.out.println("inner.show");
            System.out.println(age);
            //调用外部类属性
            System.out.println(Outer.this.age);//  外部类名.this.变量名
            //调用外部类方法
           // System.out.println(Outer.this.show()); 不可以打印
            Outer.this.show();//直接调用

        }
    }
}
